package com.hardy.leecode;

import java.util.LinkedList;
import java.util.Queue;

/**
 * Author: Hardy
 * Date:   2020/11/9
 * Description:
 * <p>
 * - 剑指 Offer 12. 矩阵中的路径
 * 请设计一个函数，用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始，每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格，那么该路径不能再次进入该格子。例如，在下面的3×4的矩阵中包含一条字符串“bfce”的路径（路径中的字母用加粗标出）。
 * <p>
 * [["a","b","c","e"],
 * ["s","f","c","s"],
 * ["a","d","e","e"]]
 * <p>
 * 但矩阵中不包含字符串“abfb”的路径，因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后，路径不能再次进入这个格子。
 * <p>
 * <p>
 * <p>
 * 示例 1：
 * <p>
 * 输入：board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
 * 输出：true
 * 示例 2：
 * <p>
 * 输入：board = [["a","b"],["c","d"]], word = "abcd"
 * 输出：false
 * 提示：
 * <p>
 * 1 <= board.length <= 200
 * 1 <= board[i].length <= 200
 **/
public class QueOffer12 {
    public static void main(String[] args) {

        char[][] board = {{'C', 'A', 'A'}, {'A', 'A', 'A'}, {'B', 'C', 'D'}};
        String w = "AAB";

        System.out.println(new Solution().exist(board, w));
    }

    static class Solution {
        public boolean exist(char[][] board, String word) {
            char c = word.charAt(0);
            for (int i = 0; i < board.length; i++) {
                for (int j = 0, k = board[i].length - 1; j <= k; j++, k--) {
                    if (board[i][j] == c) if (fbs(board, i, j, word, 1)) return true;
                    if (j != k && board[i][k] == c) if (fbs(board, i, k, word, 1)) return true;
                }
            }
            return false;
        }

        public boolean fbs(char[][] board, int i, int j, String word, int idx) {
            if (idx >= word.length()) return true;

            char ch = board[i][j];
            board[i][j] = '-';
            char c = word.charAt(idx++);

            if (i - 1 >= 0 && board[i - 1][j] == c) if (fbs(board, i - 1, j, word, idx)) return true;
            if (i + 1 < board.length && board[i + 1][j] == c) if (fbs(board, i + 1, j, word, idx)) return true;

            if (j - 1 >= 0 && board[i][j - 1] == c) if (fbs(board, i, j - 1, word, idx)) return true;
            if (j + 1 < board[i].length && board[i][j + 1] == c) if (fbs(board, i, j + 1, word, idx)) return true;

            board[i][j] = ch;
            return false;
        }
    }
}
